package org.dreamwork.jasmine2.restful.client.gui.util;

import org.dreamwork.jasmine2.restful.MethodType;
import org.dreamwork.jasmine2.restful.client.gui.model.ParameterHolder;
import org.dreamwork.jasmine2.restful.client.gui.model.ParameterTableModel;
import org.dreamwork.misc.XMLUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: seth.yang
 * Date: 2014/12/14
 * Time: 3:08
 */
public class ParameterUtil {
    public static void save (File file, boolean encrypted, MethodType type, ParameterTableModel context, ParameterTableModel parameters, String body) throws IOException {
        FileOutputStream fos = new FileOutputStream (file);
        PrintWriter out = new PrintWriter (fos, true);
        try {
            out.println ("<?xml version='1.0' encoding='utf-8'?>");
            out.printf ("<saved-parameter type='%s' encrypted='%s'>%n", type, encrypted);
            if (context != null && context.getParameters () != null) {
                for (ParameterHolder holder : context.getParameters ().values ()) {
                    out.printf (
                            "<context-parameter name='%s' type='%s'><![CDATA[%s]]></context-parameter>%n",
                            holder.getName (), holder.getType (), holder.getValue ()
                    );
                }
            }
            if (type == MethodType.GET && parameters != null && parameters.getParameters () != null) {
                for (ParameterHolder holder : parameters.getParameters ().values ()) {
                    out.printf (
                            "<api-parameter name='%s' type='%s'><![CDATA[%s]]></api-parameter>%n",
                            holder.getName (), holder.getType (), holder.getValue ()
                    );
                }
            } else if (type == MethodType.POST) {
                out.printf ("<body><![CDATA[%s]]></body>", body);
            }
            out.printf ("</saved-parameter>");
            out.flush ();
        } finally {
            out.flush ();
            out.close ();
            fos.flush ();
            fos.close ();
        }
    }

    public static Map<String, Object> load (File file) throws Exception {
        Document doc = XMLUtil.parse (file);
        Map<String, Object> map = new HashMap<String, Object> ();
        Element root = doc.getDocumentElement ();
        map.put ("encrypted", Boolean.valueOf (root.getAttribute ("encrypted")));
        map.put ("type", MethodType.parse (root.getAttribute ("type")));
        NodeList list = root.getElementsByTagName ("context-parameter");
        if (list != null && list.getLength () > 0) {
            map.put ("context", createMap (list));
        }
        list = root.getElementsByTagName ("api-parameter");
        if (list != null && list.getLength () > 0) {
            map.put ("parameters", createMap (list));
        }
        list = root.getElementsByTagName ("body");
        if (list != null && list.getLength () > 0) {
            map.put ("body", list.item (0).getTextContent ());
        }

        return map;
    }

    private static Map<String, ParameterHolder> createMap (NodeList list) {
        Map<String, ParameterHolder> holders = new HashMap<String, ParameterHolder> ();
        for (int i = 0; i < list.getLength (); i ++) {
            Element e = (Element) list.item (i);
            String type = e.getAttribute ("type");
            ParameterHolder holder = new ParameterHolder ();
            holder.setName (e.getAttribute ("name"));
            holder.setType (type);
            String value = e.getTextContent ();
            if ("null".equals (value)) continue;
            holder.setValue (value.trim ());
            holders.put (holder.getName (), holder);
        }
        return holders;
    }
}